package Code.Objects.Characters.Enemies;

import org.jrabbit.base.data.iter.UpdateList;
import org.jrabbit.base.graphics.transforms.Vector2d;
import org.jrabbit.base.managers.ResourceManager;

import Code.Basic.Entity.GenericCharacter;
import Code.Objects.Characters.Enemies.Shredder.Shredder;
import Code.Objects.Characters.Enemies.RangedEnemyTest;

public class EnemyGenerator 
{
	private final int MAX_ENEMIES_DEFAULT = 10;
	private final double GENERATE_INTERVAL_DEFAULT = 0.5;
	private final double MIN_DISTANCE_DEFAULT = 1000;
	private final double REGENERATE_DISTANCE = 800;
	
	protected GenericCharacter owner;
	
	protected boolean enabled;
	
	// Future possibility to add other enemies to randomly pick here
	protected boolean enemiesToGenerate[];
	
	protected int maxEnemies;
	protected UpdateList<GenericCharacter> curEnemies;
	
	protected int enemyCounter;
	protected double minGenerateInterval;
	protected double timer;
	protected double minDistance;
	
	public EnemyGenerator(GenericCharacter c, int mE, double eI, double d)
	{
		owner = c;
		enemyCounter = 0;
		maxEnemies = mE;
		minGenerateInterval = eI;
		minDistance = d;
		curEnemies = new UpdateList<GenericCharacter>();
		//enabled = true;
		enemiesToGenerate = new boolean[10];
      
    // test for both shredder and ranged enemy
    defineEnemyAppearance(0, true);
    defineEnemyAppearance(1, true);  
	}
	
	public EnemyGenerator(GenericCharacter c)
	{
		owner = c;
		maxEnemies = MAX_ENEMIES_DEFAULT;
		minGenerateInterval = GENERATE_INTERVAL_DEFAULT;
		minDistance = MIN_DISTANCE_DEFAULT;
		curEnemies = new UpdateList<GenericCharacter>();
		enemiesToGenerate = new boolean[10];
		enemiesToGenerate[0] = true;
	}
	
	public void defineEnemyAppearance(int enemyNum, boolean setting)
	{
		if (enemyNum >= 0 && enemyNum < enemiesToGenerate.length)
		{
			enemiesToGenerate[enemyNum] = setting;
		}	
	}
	
	public void setParameters(int mE, double mD)
	{
		if (mE > 0)
		{
			maxEnemies = mE;
		}
		
		if (mD > 300)
		{
			minDistance = mD;
		}
	}
	
	public void Enable()
	{
		enabled = true;
	}
	
	public void Disable()
	{
		enabled = true;
	}
	
	public boolean isEnabled()
	{
		return enabled;
	}
	
	public void toggleEnabled()
	{
		if (!enabled)
		{
			enabled = true;
		}
		else
		{
			enabled = false;
		}
	}
	
	private void createEnemy()
	{
		// In the future when using multiple enemies, select randomly here
    if (ResourceManager.random().nextInt(2) < 1)
    {
      Shredder e = new Shredder();
    }
    else
    {
      RangedEnemyTest e = new RangedEnemyTest();
    }  
      
		owner.getWorld().addCharacter(e, "Small Enemies");
		
		Vector2d loc = owner.location().copy();
		loc.addPolar((ResourceManager.random().nextDouble() + 1) * minDistance, 
				(ResourceManager.random().nextDouble()) * Math.PI);
		e.setLocation(loc);
		e.setTarget(owner);
		
		
		curEnemies.add(e);
		enemyCounter++;
		//System.out.printf("New Enemy generated: %d of %d\n", enemyCounter, maxEnemies);
	}
	
	public void generate(int delta)
	{
		for (GenericCharacter e:curEnemies)
		{
			// Check when enemies die to allow for new ones to appear
			if (!e.isAlive())
			{
				curEnemies.remove(e);
				enemyCounter--;
			}
			
			// Check if distance between enemies to player is great enough to relocate
			if(owner.location().distanceTo(e.location()) > REGENERATE_DISTANCE)
			{
				e.location().set(owner.location());
				e.location().addPolar((ResourceManager.random().nextDouble() + 1) * minDistance, 
						(ResourceManager.random().nextDouble()) * Math.PI);
			}
		}
		curEnemies.release();
		
		timer += delta;
		
		if (timer > minGenerateInterval)
		{	
			timer -= minGenerateInterval;
			if (enemyCounter < maxEnemies)
			{
				createEnemy();
				timer = 0;
			}
		}
	}
}
